//*********************************************************************
//		Copyright (c) 2003 - 2008 Microsoft Corporation.
//      This code is provided under Microsoft Public License, which can be found at
//      http://www.microsoft.com/resources/sharedsource/licensingbasics/publiclicense.mspx 
//
// @File: Main.cs
//
// Purpose: Constants, settigns and the application entry-point
//
//
//
// Notes: 
//
//
//	
// History: 
//     @Version: V2.1
//
//     08/24/07 PGV 2.1.001.0 Starting V2.1 (based on 2.0.030.0 code)
//
//
// @EndHeader@
//*********************************************************************


using System;
using System.IO;
using System.Data.SqlClient;

namespace H2V2
{

	public sealed class CmdLineArg
	{
		public static uint ManagerOptions	= 0xffff;
		public static bool bExplicitOptions = false; 
		public static uint DebugTargetOptions = 0;
		public static bool bDebugTargetOptions = false;

		public static uint DebugCollectorSqlOptions = 0x7fffffff;
		public static bool bDebugCollectorSqlOptions = false;
		public static uint DebugCollectorLogOptions = 0x7fffffff;
		public static bool bDebugCollectorLogOptions = false;
		public static uint DebugCollectorWmiOptions = 0x7fffffff;
		public static bool bDebugCollectorWmiOptions = false;

		public static string ConfigFile		= "H2Config.xml";
		public static bool bJumpLog;

		// Exporter
		public static bool bExporterForceSid  = false;
		public static uint ForceSid			= 0;
		public static bool bExporterForceDate = false;
		public static DateTime ForceDate	= DateTime.MinValue;
		public static bool bExporterRetainFiles = false;
		public static bool bCallWatson		= true;

		// DateFormat
		public static bool bCustomDateFormat = false;
		public static string CustomDateFormat = ""; 
		public static bool bBcpRSwitch = false;

		public static string [] Args;
	}

	public sealed class Constants
	{
        public static readonly Version ver = new Version (((System.Reflection.AssemblyFileVersionAttribute)
            (System.Reflection.Assembly.GetExecutingAssembly ().GetCustomAttributes (
            typeof (System.Reflection.AssemblyFileVersionAttribute), false)[0])).Version);
        public static readonly DateTime filestamp = File.GetLastWriteTime (System.Reflection.Assembly.GetExecutingAssembly ().ManifestModule.FullyQualifiedName);
        public static readonly string Version = ver + " " + filestamp.ToString (); 

		public static string	RepositoryServer;
		public static string	RepositoryDB;
        public static string    QuotedRepositoryDB;
		public static string	ConfigFileName = "H2Config.xml";
		public static bool		VerboseLogging = false;
        public static bool      DeleteFiles = true;
        public static bool      JumpLog = true;
        
        // v2.1 - config file is ignored. 
        //Export is forced by command-line switches only (still subject to the Repository config). 
		public static bool		ExportData = false;

		public const uint		REPOSITORY_VERSION = 116;
		public static int		RepositoryVersion;
		public static int		RepositoryTimeout = 60;

        // matches SQL Server DateTime=0
		public static DateTime	MIN_DATE = new DateTime (1990,1,1);
	}

	class Commander
	{
		[STAThread]
		static void Main(string[] args)
		{
			string s, sraw;
			char key;
			uint ui;
			string user = null, 
				pwd = null;

			Console.WriteLine ("H2 Collector   ver. "+Constants.Version);

			CmdLineArg.Args = args;

			foreach (string a in args)
			{
				if (a[0] != '/' && a[0] != '-') 
				{
					ShowUsage (a);
					return;
				}

				try
				{
					key = a[1];
					sraw = a.Substring (2);
                    s = sraw.ToUpper ();
					switch (key)
					{
						case '?':
							ShowUsage ("");
							return;
						case 'C':
							Path.GetFileName (s); 
							CmdLineArg.ConfigFile = s;
							Constants.ConfigFileName = s; 
							break;
						case 'D':
							if (s != "MDY" && s != "DMY" && s != "YDM" && s != "YMD" && s != "MYD" && s != "DYM") 
							{
								Console.WriteLine ();
								return;
							}
							else
							{
								CmdLineArg.bCustomDateFormat = true;
								CmdLineArg.CustomDateFormat = s;
							}
							break;
						case 'd':
							CmdLineArg.bBcpRSwitch = true; 
							break;
						case 'x': 
							if (s.StartsWith ("0X")) ui = Convert.ToUInt32 (s, 16);
							else ui = Convert.ToUInt32 (s);
							CmdLineArg.ManagerOptions = ui;
							CmdLineArg.bExplicitOptions = true;
							break;
						case 'f':
							CmdLineArg.ForceSid = Convert.ToUInt32 (s); 
							CmdLineArg.bExporterForceSid = true;
                            // v2.1 - using this flag will forse Export
                            Constants.ExportData = true;
                            break;
						case 'F':
							DateTime dt = DateTime.Parse (s);
							CmdLineArg.ForceDate = dt;
							CmdLineArg.bExporterForceDate = true;
                            // v2.1 - using this flag will forse Export
                            Constants.ExportData = true;
							break;
						case 'E':
							ushort e = Convert.ToUInt16 (s); 
							CmdLineArg.bExporterRetainFiles = (e == 1);
							break;
						case 'W':
                            // in v2 the switch was used to control watson (W1 - use watson; W0 - not use watson)
                            // v2.1:  
                            // W0 - works as before (export, but don't send, just pack)
                            // W1 - does nothing
							ushort w = 0;
                            if (!String.IsNullOrEmpty (s))
                            {
                                w = Convert.ToUInt16 (s);
                            }
							Constants.ExportData = (w == 0);
							break;
						case 'J':
							int j = Convert.ToInt32 (s);
							CmdLineArg.bJumpLog = (j == 1);
							Constants.JumpLog = CmdLineArg.bJumpLog;
							break;
						case 't': 
							if (s.StartsWith ("0X")) ui = Convert.ToUInt32 (s, 16);
							else ui = Convert.ToUInt32 (s);
							CmdLineArg.DebugTargetOptions = ui;
							CmdLineArg.bDebugTargetOptions = true;
							break;
						case 'r': 
							char ckey = s[0];
							s = s.Substring (1);
							switch (ckey)
							{
							case 'S':
								if (s.StartsWith ("0X")) ui = Convert.ToUInt32 (s, 16);
								else ui = Convert.ToUInt32 (s);
								CmdLineArg.DebugCollectorSqlOptions = ui;
								CmdLineArg.bDebugCollectorSqlOptions = true;
								break;
							case 'L':
								if (s.StartsWith ("0X")) ui = Convert.ToUInt32 (s, 16);
								else ui = Convert.ToUInt32 (s);
								CmdLineArg.DebugCollectorLogOptions = ui;
								CmdLineArg.bDebugCollectorLogOptions = true;
								break;
							case 'W':
								if (s.StartsWith ("0X")) ui = Convert.ToUInt32 (s, 16);
								else ui = Convert.ToUInt32 (s);
								CmdLineArg.DebugCollectorWmiOptions = ui;
								CmdLineArg.bDebugCollectorWmiOptions = true;
								break;
							default:
								ShowUsage (a);
								return;
							}
							break;
						case 'U':
                            user = sraw;
							break;
						case 'P':
                            pwd = sraw;
							for (int i=0; i < CmdLineArg.Args.Length; i++)
							{
								if (CmdLineArg.Args[i][1] == 'P')
								{
									CmdLineArg.Args[i] = String.Empty;
								}
							}
							break;
						default:
							ShowUsage (a);
							return;
					}
				}
				catch (Exception ex)
				{
					string m = ex.Message;
					ShowUsage (a);
					return;
				}
			}

			if (!ValidateArgs ()) return;

			try
			{
				H2Manager mgr = new H2Manager ();
				if (!mgr.Init (user, pwd)) return;
				mgr.Run ();
				mgr.Close ();
			}
			catch (Exception ex)
			{
				Console.WriteLine (ex.Message);
				Console.WriteLine ("H2 shuts down");
			}
		}

		static void ShowUsage (string arg)
		{
			if (arg != "") Console.WriteLine ("Incorrect or unknown argument "+arg);
			Console.WriteLine ("Usage: "+Environment.NewLine
				+"sqlh2 [/Cfilename] [/Ddateformat] [/d]"+Environment.NewLine
				+"C - configuration file "+Environment.NewLine
				+"D - sets dateformat for SQL Server connections (available formats - MDY, DMY, YDM, YMD, MYD, DYM) "+Environment.NewLine
				+"d - supply R switch for bcp calls (for performance data loading) "+Environment.NewLine
				//+"x - manager options "+Environment.NewLine
				//+"f - repeat export of session N (N - number > 0) - overrides F, if /F is present"+Environment.NewLine
				//+"F - export data timestamped after DateTime - ignored, if /f is present "+Environment.NewLine
				//+"J - Log 'JUMP' algorithm 1 - ON, 0 - OFF "+Environment.NewLine
				);
			}

		static bool ValidateArgs ()
		{
			if (CmdLineArg.bExporterForceSid && CmdLineArg.bExporterForceDate)
			{
				Console.WriteLine ("Keys /F and /f are incompatible. /F date will be ignored.");
				CmdLineArg.bExporterForceDate = false;
			}
			if (CmdLineArg.bExporterForceSid && (CmdLineArg.ForceSid == 0))
			{	
				Console.WriteLine ("Exporter sid (/f) can't be 0");
				return false;
			}

			return true;
		}
	}

}
